/// \file DXEngine.h
/// \date 15/02/2010
///
/// \brief Application class (DXinit, windows proc)
///
#ifndef __DXENGINE_H__
#define __DXENGINE_H__


#include "DXEngineTimer.h"
#include "DXEngineInput.h"
#include "DXEngineCommon.h"
#include "Engine.h"
#include "SceneGraph.h"
// Windows
#include <windows.h>
// DirectX
#include <d3d9.h>
#include <D3dx9core.h>
#include <string>



class CDXEngine : public IEngine
{
public:

	virtual ~CDXEngine();
	virtual bool				init(const char* strWinTitle,
								unsigned int uiWinWidth,
								unsigned int uiWinHeight,
								bool m_bWindowed);

	virtual bool				update();
	virtual bool				render(SceneGraphPtr scene);
	virtual void				shutdown();

	static CDXEngine*			getInstance();

	inline LPDIRECT3DDEVICE9	getD3DDevice() { return  m_pD3DDevice; }

private:
	// Has to be a Singleton
	CDXEngine();
	CDXEngine(const CDXEngine&);
	CDXEngine& operator=(const CDXEngine&);

	// Windows specific information
	WNDCLASS				m_wc;					//!< application's class
	HWND					m_hWnd;					//!< Main Window Handle
	HINSTANCE				m_hInst;
	unsigned int			m_uiWinWidth;
	unsigned int			m_uiWinHeight;
	bool					m_bWindowed;

	// DirectX specific information
	LPDIRECT3D9				m_pD3D;					//!< Pointer to Direct3D Object
	LPDIRECT3DDEVICE9		m_pD3DDevice;			//!< Pointer to Direct3D Device Object
	D3DPRESENT_PARAMETERS	m_D3DPresentParams;		//!< Struct to present D3D parms
	D3DDEVTYPE				m_deviceType;			//!< We need the value to set correct vertex buffer parameters. Only initialized in the begining.
	DWORD					m_deviceBehavior;		//!< We need the value to set correct vertex buffer parameters. Only initialized in the begining.
	// Input
	DXEngineInputPtr		m_pInput;
	// Time Information
	DXEngineTimerPtr		m_pTimer;


	void					resetDevice();

	// CDXEngine_Init.cpp
	bool					initDisplay(LPCSTR strWinTitle);
	ATOM					localRegisterClass(LPCSTR strWinTitle);
	bool					initDirect3D(void);
	D3DFORMAT				findDepthStencilFormat(ULONG adapterOrdinal,
												D3DFORMAT Format,
												D3DDEVTYPE devType);
	D3DFORMAT				findBackBufferFormat(ULONG adapterOrdinal,
												D3DDEVTYPE devType,
												BOOL bWindowed);
	bool					createDev(void);
	bool					initFont(void);
	bool					checkShader(void);


	static LRESULT CALLBACK		wndProc(HWND hWnd,
									UINT message, 
									WPARAM wParam, 
									LPARAM lParam);
};



#endif //  __DXENGINE_H__